#ifndef CAP_CNODE_H
#define CAP_CNODE_H

#include <seminix/spinlock.h>
#include <cap/cap.h>

typedef struct cnode {
    cap_t **cnode_root;
    unsigned long *full_bits;
    int      cnode_max;
    int      cnode_first;
    int      cnode_used;
} cnode_t;

typedef struct cap_cnode {
    cap_t cap;
    spinlock_t *cnode_lock;
    cnode_t **cnode;
} cap_cnode_t;

extern const struct cap_ops cnode_cap_ops;

int cnode_get_unused_slot(cap_cnode_t *cap_cnode);
void cnode_cap_free_slot(cap_cnode_t *cap_cnode, int index);
static inline void cnode_cap_free_slot_cap(cap_t *cap)
{
    cnode_cap_free_slot(cap->cap_cnode, cap->index);
}
void cnode_cap_insert_slot(cap_cnode_t *cap_cnode, int index, cap_t *cap);

#define CAPTYPE_NOTVERIFY   (cap_count_max + 1)

cap_t *cnode_capget(int cd, int cap_type);
void cnode_capput(cap_t *cap);

cap_cnode_t *cnode_get(int cnode);
static inline void cnode_put(cap_cnode_t *cap_cnode)
{
    capput(&cap_cnode->cap);
}

#endif /* !CAP_CNODE_H */
